package com.hs.mod_archive

import android.app.Service
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.IBinder
import android.util.Log
import com.hs.framework.utils.MMKVUtil
import com.hs.room.model.archive.OptLog
import com.hs.room.repository.SysLogRepository
import com.hs.room.repository.service.IDevRepository
import com.hs.room.repository.service.ILogRepository
import com.hs.serial.Cmd
import com.hs.serial.SerialPortManager
import com.hs.serial.TtyUtils
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import java.util.concurrent.Executors
import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.ScheduledFuture
import java.util.concurrent.TimeUnit
import java.util.regex.Pattern
import javax.inject.Inject

@AndroidEntryPoint
class ScheduleService : Service(), (ByteArray) -> Unit {
    private var lastOptTime: Long = 999999999999999999L
    private var sysCount: Int = 0

    private val job = CoroutineScope(SupervisorJob() + Dispatchers.IO)

    @Inject
    lateinit var sysLogRepository: SysLogRepository
    var lastOpt: OptLog? = null

    @Inject
    lateinit var service: ILogRepository

    @Inject
    lateinit var devService: IDevRepository
    private var scheduler: ScheduledExecutorService? = null

    private val tasks: MutableMap<String, ScheduledFuture<*>> = HashMap(15)

    private var receiver: BroadcastReceiver? = null

    override fun onCreate() {
        super.onCreate()
        Log.d("ScheduleService", "onCreate")
        receiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context, intent: Intent) {
                //插入识别记录
                if (intent.action == Const.ACT_CONFIG_SERIAL_INTERFACE) {
                    initSerialTasks()
                    //                    insertRecognizeRecord(intent);
                }
            }
        }

        registerReceiver(receiver, IntentFilter(Const.ACT_CONFIG_SERIAL_INTERFACE))
    }

    override fun onBind(intent: Intent): IBinder? {
        return null
    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        Log.d("ScheduleService", "onStartCommand")
        scheduler = Executors.newScheduledThreadPool(5)
//        initData()
        initTasks()
        initSerialTasks()
        return START_STICKY
    }

    fun ByteArray.hexStr(): String {
        return joinToString("") { "%02X".format(it) }
    }

    private fun initSerialTasks() {
        val r = MMKVUtil.getInt(TtyUtils.K_LOCK_RATE, TtyUtils.bRate[0])
        val i = MMKVUtil.getString(TtyUtils.K_LOCK_PATH, TtyUtils.ttys[0])

        SerialPortManager.getInstance().initSerialPort(i, r, this)
        openRunningLamp()
        tasks["checkDoor"] = startCheckDoorTask()
    }

    private fun openRunningLamp() {
        job.launch {
            devService.getLamp().collect {
                var closeLamp = byteArrayOf()
                var b = 0
                for (i in it) {
                    if (i.color == 2)
                        SerialPortManager.getInstance().execCmd(Cmd.openLamp(i.boardId, i.lockNo))
                    else {
                        b = i.boardId
                        closeLamp = closeLamp.plus(i.lockNo.toByte())
                    }
                }
                SerialPortManager.getInstance().execCmd(Cmd.closeLamp(b, closeLamp))
            }
        }
    }


    private fun initTasks() {
        startOptTask()
//        tasks["opt"] =
//        tasks["rebootDevice"] = startRebootDeviceTask()
//        tasks["cleanData"] = startCleanDataTask()
//        tasks["syncSettingsToPlatform"] = startSettingSyncTask()
//        tasks["uploadMediaToPlatform"] = startMediaUploadTask() //从app上传媒体资源到平台，app 默认显示设置的图片或视频
//        tasks["downloadMediaFromPlatform"] = startMediaDownloadTask() //从平台下载媒体资源，app 默认显示设置的图片或视频资源
//        tasks["downloadUserAvatarFromPlatform"] = startUserAvatarDownloadTask() //从平台下载用户头像并添加到人脸库
//        tasks["syncUserInfoToPlatform"] = startUserInfoSyncTask() //从app同步用户头像及密码到平台
//        tasks["uploadRecognizeResult"] = startRecognizeResultUploadTask() //上传识别结果到平台
//        tasks["getDepartsFromPlatform"] = startDepartsQueryTask() //查询部门数据
//        tasks["queryDevicePositionAndCleanliness"] =
//            startDevicePositionAndCleanlinessQueryTask() //查询设备位置及洁净等级
//        tasks["getPositionsFromPlatform"] = startPositionsQueryTask() //查询岗位数据
//        tasks["getUsersFromPlatform"] = startUserQueryTask() //从平台查询用户数据
    }

    private fun startOptTask(): ScheduledFuture<*> {
        job.launch {
            service.getLastOpt().collect {
                lastOpt = it
            }
        }
        return scheduler!!.scheduleWithFixedDelay({
            try {
                val count = sysLogRepository.count()
                if (count == sysCount) {//大于一分钟未操作通知界面返回到主页
                    sendBroadcast(Intent(Const.ACT_ACTIVITY_DETECTION))
                } else {
                    lastOptTime = System.currentTimeMillis()
                }
                sysCount = count
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }, 0, 1, TimeUnit.MINUTES)
    }

    private fun startCheckDoorTask(): ScheduledFuture<*> {
        return scheduler!!.scheduleWithFixedDelay({
            val l = devService.getDevCabinetBoardId()
            l.forEach({
                SerialPortManager.getInstance().execCmd(Cmd.checkDoor(it))
            })
        }, 0, 1, TimeUnit.MINUTES)
    }

    private fun startDevicePositionAndCleanlinessQueryTask(): ScheduledFuture<*> {
        return scheduler!!.scheduleWithFixedDelay({
            Log.d(
                TAG,
                "run startDevicePositionAndCleanlinessQueryTask"
            )
        }, 0, 1, TimeUnit.HOURS)
    }

    private fun startUserQueryTask(): ScheduledFuture<*> {
        return scheduler!!.scheduleWithFixedDelay({
            Log.d(TAG, "run startDepartsQueryTask")
        }, 0, 1, TimeUnit.HOURS)
    }

    private fun startPositionsQueryTask(): ScheduledFuture<*> {
        return scheduler!!.scheduleWithFixedDelay({
            Log.d(TAG, "run startDepartsQueryTask")
        }, 0, 1, TimeUnit.HOURS)
    }

    private fun startDepartsQueryTask(): ScheduledFuture<*> {
        return scheduler!!.scheduleWithFixedDelay({
            Log.d(TAG, "run startDepartsQueryTask")
        }, 0, 1, TimeUnit.HOURS)
    }

    private fun insertRecognizeRecord(intent: Intent) {
//        try {
//
//            RecognizeRecordBean recognizeBean = new RecognizeRecordBean(
//                    intent.getStringExtra("realName"),
//                    Integer.valueOf(intent.getStringExtra("sex")),
//                    intent.getStringExtra("workNo"),
//                    intent.getStringExtra("idCard"),
//                    intent.getStringExtra("departName"),
//                    intent.getStringExtra("positionName"),
//                    intent.getStringExtra("way"),
//                    LocalDateTime.now(),
//                    String.valueOf(intent.getIntExtra("result",1)));
//
//            SqliteHelper.getInstance().insertRecognizeRecord(recognizeBean);
//
//        } catch (Exception e) {
//            Log.e(TAG, "insert recognize record error:"+e.getMessage(), e);
//        }
    }

    private fun startRecognizeResultUploadTask(): ScheduledFuture<*> {
        return scheduler!!.scheduleWithFixedDelay({
            Log.d(TAG, "run startRecognizeResultUploadTask")
        }, 0, 15, TimeUnit.SECONDS)
    }

    //    private void finishTask(TaskBean task,String errMsg){
//        task.setStatus(StringUtils.isEmpty(errMsg)?TaskBean.STATUS_FINISH:TaskBean.STATUS_ERROR);
//        task.setErrorMsg(errMsg);
//        TaskHelper.updateTask(task);
//    }
    private fun startUserInfoSyncTask(): ScheduledFuture<*> {
        return scheduler!!.scheduleWithFixedDelay({
            Log.d(TAG, "run startUserInfoSyncTask")
        }, 0, 5, TimeUnit.SECONDS)
    }


    /**
     * 同平台同步用户图像并添加到人脸库
     *
     * @return
     */
    private fun startUserAvatarDownloadTask(): ScheduledFuture<*> {
        return scheduler!!.scheduleWithFixedDelay({
            Log.d(TAG, "run startUserAvatarDownloadTask")
        }, 0, 15, TimeUnit.SECONDS)
    }

    private fun startMediaDownloadTask(): ScheduledFuture<*> {
        return scheduler!!.scheduleWithFixedDelay({
            Log.d(TAG, "run startRebootDeviceTask")
        }, 0, 5, TimeUnit.SECONDS)
    }

    private fun startMediaUploadTask(): ScheduledFuture<*> {
        return scheduler!!.scheduleWithFixedDelay({
            Log.d(TAG, "run startMediaUploadTask")
        }, 0, 5, TimeUnit.SECONDS)
    }

    private fun startSettingSyncTask(): ScheduledFuture<*> {
        return scheduler!!.scheduleWithFixedDelay({
            Log.d(TAG, "run startSettingSyncTask")
        }, 0, 5, TimeUnit.SECONDS)
    }

    private fun startCleanDataTask(): ScheduledFuture<*> {
        return scheduler!!.scheduleWithFixedDelay({
            Log.d(TAG, "run startCleanDataTask")
        }, 0, 5, TimeUnit.SECONDS)
    }

    /**
     * 执行重启设备的任务
     */
    private fun startRebootDeviceTask(): ScheduledFuture<*> {
        return scheduler!!.scheduleWithFixedDelay({
            Log.d(TAG, "run startRebootDeviceTask")
        }, 0, 5, TimeUnit.SECONDS)
    }

    override fun onDestroy() {
        tasks.values.forEach {
            it.cancel(true)
        }
        SerialPortManager.getInstance().close()
        scheduler?.shutdown()
        unregisterReceiver(receiver)
        job.cancel()
        super.onDestroy()
    }

    companion object {
        private const val TAG = "scheduleService"

        private val DATE_PATTERN: Pattern = Pattern.compile("^/\\d{4}-\\d{2}-\\d{2}.*")
    }

    /**
     * 名称       起始符 帧长度 板地址 指令字 数据域     校验
     * 长度(字节)   4       1   1       1   n       1
     *
     * 命令字 说明 备注
     * 0x82 开锁
     * 0x83 读取单个锁状态
     * 0x84 读取所有锁状态
     * 0x86 开全部锁
     * 0x87 开多个锁
     * 0x88 锁通道持续输出 该指令用于控制长时间通电的外设，例如照明灯，继电器
     * 0x89 锁通道输出关闭
     * 0x93 同时开多个锁 主要用于同一个大箱门上安装了多个锁的情况
     */
    override fun invoke(data: ByteArray) {
        try {
            println(data.hexStr())
            if (true) {//检查有门没关&&最后一条操作日志时间大于一分钟 亮红灯 语音提示
//                574B4C591C0184001201010100000000000000000000000000000083

            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
}
